package com.archermind.boc.ehcache;

import java.util.ArrayList;

import java.util.List;
import java.util.Random;

import com.archermind.boc.Logger;
import com.archermind.boc.dal.business.support.DispatchSupport;
import com.archermind.boc.domain.Biz;
import com.archermind.boc.domain.BizStatus;
import com.archermind.boc.domain.IQ;
import com.archermind.boc.socket.out.IBocSocketWriter;
import com.archermind.sessionpool.BizSessionPool;

import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;

public class UserEhcacheImpl implements EhcacheInterface {

	private static Logger log = Logger.getLogger(UserEhcacheImpl.class
			.getName());
	private static final String USER_CACHE = "[user cache]";
	IBocSocketWriter bocs;

	public IBocSocketWriter getBocs() {
		return bocs;
	}

	public void setBocs(IBocSocketWriter bocs) {
		this.bocs = bocs;
	}

	public void addElement(UserCache userCache) {
		Cache cache = EhcacheUtil.getCache();
		Element e = new Element(userCache.getUserid(), userCache);
		cache.put(e);
		log.info(USER_CACHE + " add new user, user id: "
				+ userCache.getUserid());
	}

	public UserCache getUserCacheById(int userid) {
		Cache cache = EhcacheUtil.getCache();
		Element e = cache.get(userid);
		if (e != null) {
			UserCache uc = (UserCache) e.getObjectValue();
			return uc;
		} else {
			return null;
		}

	}

	public List<UserCache> getUserCacheByBizid(int bizid) {
		List<UserCache> ls = new ArrayList<UserCache>();
		List<Integer> keys = findAllKey();
		if (keys != null && keys.size() > 0) {
			for (int key : keys) {
				UserCache uc = getUserCacheById(key);
				if (uc.getBiz() != null) {
					if (uc.getBiz().getBizid() == bizid) {
						ls.add(uc);
					}
				}
			}
		}
		return ls;
	}

	/**
	 * 超时或授权完毕时 释放biz对象
	 * 
	 * @param ls
	 */
	public void releaseBiz(List<UserCache> ls) {
		for (UserCache uc : ls) {
			UserCache user = getUserCacheById(uc.getUserid());
			user.setBiz(null);
			user.setIsBusy(UserStatus.USER_LEISURE);
			log.info(USER_CACHE + " release the biz on user,set , user id: "
					+ user.getUserid());
		}
	}

	public void removeElementById(int userid) {
		Cache cache = EhcacheUtil.getCache();
		cache.remove(userid);
	}

	public void modifyStatus(int userid, String status) {
		UserCache uc = getUserCacheById(userid);
		uc.setStatus(status);
	}

	public void modifyBusy(int userid, String busy) {
		UserCache uc = getUserCacheById(userid);
		uc.setIsBusy(busy);
	}

	@SuppressWarnings("unchecked")
	public List<Integer> findAllKey() {
		Cache cache = EhcacheUtil.getCache();
		List<Integer> keys = cache.getKeys();
		return keys;
	}

	public static boolean isSuitableUser(UserCache userCache) {
		boolean state = false;
		if (UserStatus.USER_SIGNIN.equals(userCache.getStatus())
				&& UserStatus.USER_GRANT.equals(userCache.getRole())) {
			state = true;
		}
		return state;
	}

	public List<UserCache> getSuitableUserList() {
		List<UserCache> list = new ArrayList<UserCache>();
		List<Integer> keys = findAllKey();
		if (keys != null && keys.size() > 0) {
			for (int key : keys) {
				UserCache uc = getUserCacheById(key);
				if (isSuitableUser(uc)) {
					list.add(uc);
				}
			}
		}
		return list;
	}

	public UserCache suitableUser(int userid, Biz biz) {
		List<UserCache> list = getSuitableUserList();
		List<UserCache> leisureList = new ArrayList<UserCache>();
		int leisureNum = 0;
		for (UserCache uc : list) {
			if (uc.getIsBusy().equals(UserStatus.USER_LEISURE)) {
				leisureNum++;
				leisureList.add(uc);
			}
		}

		if (leisureNum == 0) {
			// 全忙
			// log.info("no grant banker!");
			// backToOperator(userid, biz);
			return null;
		} else if (leisureNum == 1) {
			// 一个空闲
			return leisureList.get(0);
		} else {
			// 多个空闲
			Random random = new Random(0);
			int num = random.nextInt(leisureList.size() + 1);
			return leisureList.get(num);
		}

	}

	public void modifyUserCache(UserCache userCache) {
		Cache cache = EhcacheUtil.getCache();
		cache.remove(userCache.getUserid());
		Element e = new Element(userCache.getUserid(), userCache);
		cache.put(e);
	}

	public UserCache getUserCachebySessionId(String sessionID) {
		UserCache userCache = null;
		List<Integer> keys = findAllKey();
		if (keys != null && keys.size() > 0) {
			for (int key : keys) {
				UserCache uc = getUserCacheById(key);
				if (uc.getSessionID().equals(sessionID)) {
					userCache = uc;
					break;
				}
			}
		}
		return userCache;
	}

	public UserCache assignToUser(int userid, Biz biz, IQ iq) {
		log.info("userid" + userid);
		UserCache uc = suitableUser(userid, biz);
		if (uc == null) {
			Object[] oArray = new Object[4];
			oArray[0] = getUserCacheById(userid);
			oArray[1] = biz;
			oArray[3] = iq;
			OperatorQueue.getInstance().addQueue(oArray);
			return null;
		}
		uc.setIsBusy(UserStatus.USER_BUSY);
		uc.setSessionNum(uc.getSessionNum() + 1);
		return uc;
	}

	/**
	 * 全忙 现场授权
	 */
	public void backToOperator(int userid, Biz realBiz) {
		// BizService bs = new BizService();
		UserCache uc = getUserCacheById(userid);
		// Biz biz = uc.getBiz();
		log.info("usercache's biz, biz id: " + realBiz.getBizid());
		log.info("usercache's biz, biz type: " + realBiz.getBizTypeID());
		ripBizFromPool(realBiz.getBizid());
		IQ message = DispatchSupport.setManualMessage(uc.getSessionID(),
				realBiz);
		bocs.write(message);

	}

	/**
	 * 去掉bizsession pool中的session
	 */
	public void ripBizFromPool(int bizid) {

		BizSessionPool.removeBiz(bizid);
		BizSessionPool.modifyBizStatus(bizid, BizStatus.BIZSTATUS_MANUAL);
	}

}
